The most recent major version of Python is Python 3, which we shall be using in this tutorial. However, Python 2, although not being updated with anything other than security updates, is still quite popular.
With over 6 million users, the open source Anaconda Distribution is the fastest and easiest way to do Python and R data science and machine learning on Linux, Windows, and Mac OS X. It's the industry standard for developing, testing, and training on a single machine.
Anaconda gives you preinstalled tools such as Jupyter Notebooks, Spyder and RStudio. It is the one thing you will need to set up your development environment.
Please follow this tutorial to install Anaconda : Installing Anaconda on Windows
Suppose we were to write a program to read 10 strings, and merge the ones that started with a "Hi". How big would the program be?
inp_list = [input() for i in range(10)]
inp_list_2 = [i for i in inp_list if str.lower(i[:2])=="hi"]
print("".join(inp_list_2))
Hey Hi Hiya Hira h f s w e r HiHiyaHira
See how easy this is? Note that the syntax is pretty intuitive as well.
Don't worry if you can't understand anything here, soon you will be able to follow along as well. Let's dive into the basics.
We can launch Python by opening terminal and typing "python3". This opens up an interactive terminal, where you can type the commands.
Another option is to open up a text editor, type the program, save the file with a '.py' extension (instead of .docx or .txt). The name of the file will be prog_name.py, so to execute it, we go to terminal and type "python3 prog_name.py".
Errors are key to identifying the mistakes in your program. They will show up for various reasons like syntax errors and logical errors.
In languages like C, errors in syntax are brought up whether or not those statements are executed (conditional statements). In Python, unless a particular block of code is executed, even syntax errors will not show up for that block of code.
This may seem counterproductive, but as you will later see, it is the basis for how Python functions.
Syntax is nothing but the format you need to follow. They are the rules you need to adhere to.
The legendary Hello World is here.
print("Hello World!")
Hello World!
To print something, we write print followed by the thing we want to.
We enclose strings (i.e. text) in quotes. In python, we can use single quotes (' '), double quotes(" ") or triple quotes(''' ''') to do so. Triple quotes is an exclusive Python added functionality.
a = 5
A = 10
print(a)
print(A)
5 10
Did you notice - There's no semi-colon! Python statements do not require an ending semi-colon.
P.S.: Semicolons can be used though, if you have multiple statements on one line.
a=6;A=10
print(a)
print(A)
6 10
What are variables? These are containers to store temporary values. Anything you need to store, so that you can access it later in the program, is done by using a variable.
In the above code segment, a and A are variables.
A few syntax rules for variables are listed below:
Words that have a predefined meaning in the language, like print, input, list, str, int, and a lot more. As and when you find out more about the language, you will know which words add to this list.
Other important syntax rules will be covered as and when we encounter the relevant concepts.
As we saw earlier, a variable is used to store a value in memory. Just like we need to remember things before an exam in order to be able to answer questions, a computer needs to store values in order to work with them.
The concept of datatypes is crucial to programming.
What is a datatype?
It is used by languages to ensure that operations on these values are legitimate. And also because adding 2 integers is different to adding 2 strings. The process is different altogether.
What is a legitimate operation?
Consider you want to add 2 things. The only things that we consider adding are numbers, right? We can't add a character and a number. So, to ensure that what things we want to do actually make sense, programming languages use the concept of datatypes. Thus errors are detected easily.
Most languages require you to declare what kind of value will a given variable store.
The kind of values that can be stored can be categorized into these broad headings:
The most annoying thing that other languages like C have is datatype declaration in the code for a variable. Once a variable is of a particular type, it can't be changed to store another type. Python does not require this!
Does this mean the problem of checking datatypes does not exist in Python? No. Instead, Python does this checking just before execution.
How?
Python does not only store the variable value, but it also stores the type of the value stored with it.
Thus, we generally do NOT need to care about variable type, as we can reassign a variable which held an integer to now hold a string.
Now, for some examples on using variables.
Tell me which of the following are valid variable names:
my_var_1 = 10
my-var-1 = 10
print = 200
The first one is right.
The second one uses a '-', which is not allowed.
The third one tries to assign a value to a keyword, which is also not allowed.
Let's dive into Datatypes now, as it will help give you some clarity into what is all this Integer Float Double and whatnot.
an_int = 10
type(an_int)
int
An integer is used to store basic integer values (the mathematical set of integers, I/Z).
a_float = 10.0
type(a_float)
float
A float is used to store decimal values(also called floating point numbers).
an_str = 'a'
type(an_str)
str
A string can store text. It can consist of anything, we will look at them in depth later.
To take input from the user, we use input(). This returns the user input in the form of a string, we can store it in a variable.
print("Enter something")
inp = input()
Enter something
type(inp)
str
a_complex = 1+3j
type(a_complex)
complex
Python provides in-built support for the mathematical concept of a complex number.
The format is a+bj, where a and b are real values and j is a character which is essential and non-replacable. It differentiates a complex number from a real number or from looking like an addition operation.
If we want to store an imaginary number that lies on the real axis, we can use code like so:
a_complex = 2+0j
a_boolean = True
type(a_boolean)
bool
A boolean is the most basic of datatypes, which only has 2 values: True or False.
A very key concept in Python is that we can always use the same variable to store different types. Also, we may not know what type of data will the variable store, and the program will run smoothly unless you try to perform an illegitimate operation like add an integer and a string.
Now, let's move on to operators.
The base of programming lies in performing mathematical operations by using operators. We'll go over them one-by-one.
Arithmetic Operators are used to perform arithmetic operations on variables. The major ones are listed below:
The Basic Ones:
Addition = 3 + 4
Subtraction = 3 - 4
Multiplication = 3 * 4
Division = 3 / 4
Modulo = 3 % 4 #This gives the remainder of division
To perform $$x^y$$Python provides an operator.
3**4
81
We can also perform division and truncate the part after the decimal to get an integer result instead of a float (NOT rounding off) using 1 operator.
3//4
0
Relational Operators are used to perform comparisons, they always return boolean values.
The Basic Ones:
Lesser than = 3 < 4
Lesser than or equal to = 3 <= 4
Greater than = 3 > 4
greater than or equal to = 3 >= 4
To check for equality, we use ==
3==4
False
Note: a=b is an assignment operation, while a==b is to check wheter a is equal to b
To check for inequality, we use !=
3!=4
True
Assignment Operators and Shorthand Notation
The statement
a = 4
assigns a with the value 4. a is now a variable.
a+=b is a shorthand for a = a + b.
Similarly, a-=b, a=b, a/=b, a*=b,a%=b,a//=b exist.
a = 5
a+=4
print(a)
9
a = 5
a-=4
print(a)
1
a = 5
a*=4
print(a)
20
a = 5
a/=4
print(a)
1.25
a = 5
a%=4
print(a)
1
a = 5
a**=4
print(a)
625
a = 5
a//=4
print(a)
1
Logical Operators are used on boolean values. They are used to operate boolean logic.
True and False
False
True or False
True
not True
False
Membership Operator will be covered in the next lecture.
Identity Operator will be covered later.
Bitwise Operators are used to perform binary operations on numeric values.
Numbers are stored in binary format, hence bitwise operations can sometimes be useful.
& performs bit by bit AND operation of 2 numbers.
0&1
0
| performs bit by bit OR operation of 2 numbers.
0|1
1
^ performs bit by bit XOR operation of 2 numbers.
0^1
1
~ performs bit by bit 1's complement operation of a number.
~1
-2
<< performs a left shift operation on a number.
4<<2
16
>> performs a right shift operation on a number.
4>>2
1
Now, we move on to a few advanced Python data structures, which give Python the power it has.
So far we have seen built-in types like: int, float and bool. int, float, and bool are considered to be simple or primitive data types because their values are not composed of any smaller parts. They cannot be broken down.
On the other hand, strings, lists, sets, dictionaries and tuples are different from the others because they are made up of smaller pieces. In the case of strings, they are made up of smaller strings each containing one character.
Types that are comprised of smaller pieces are called collection data types. Depending on what we are doing, we may want to treat a collection data type as a single entity (the whole), or we may want to access its parts. This ambiguity is useful.
Strings are a collection of characters. They can store a line of text. Strings are arrays of bytes representing Unicode characters.
Interestingly enough, Python does not have a character datatype. It stores characters as a string of length 1.
Strings can be created by using:
Why are there 3 ways? To answer that, let's look at another question: If we want to store a sentence containing single quotes and/or double quotes, how do we do that?
The answer is we can use triple quotes to define the start and end of the string.
But what is we want to use triple quotes as well?
Thus we have something called an Escape sequence.
For characters that have special meaning in a string, we can use an escape sequence, to render that character in the string.
Didn't get a word I'm saying? I'll give you an example.
str_1 = "Hi! 'I'm Here"
This is valid
str_2 = ''' Hi! "Hello I'm here '''
This is valid as well.
str_3 = ''' Hello! I'm "Happy!" These are triple ''' quotes'''
File "<ipython-input-40-c9ff74d270a6>", line 1 str_3 = ''' Hello! I'm "Happy!" These are triple ''' quotes''' ^ SyntaxError: invalid syntax
This is not valid.
str_3 = 'Hello! I\'m "Happy!" These are triple \'\'\' quotes'
print(str_3)
Hello! I'm "Happy!" These are triple ''' quotes
Here, notice how single quotes preceded by a backslash(\) are rendered as a single quote and do not cause the string to end prematurely.
A few escape characters are mentioned below:
Since a string is a collection of characters, we can access characters individually as well from a string. To do so, we use the following syntax:
str_1 = "Hello"
print(str_1[1])
This will output 'e'.
Indexes in Python start at 0. Thus, for str_1,
Python supports negative indexing, that is the last character is stored at index -1, second last at -2 and so on.
str_1 = "Hey! Hello! Hi!"
str_1 = "Hello"
The value inside the square brackets is the index whose value you want.
print(str_1[1])
e
print(str_1[-1])
o
We can get multiple items from a string (slicing) by using a semi-colon. The emi-colon can be thought of as meaning 'everything'.
str_1[2:]
str_1[:4]
str_1[2:4]
str_1[2:]
'llo'
str_1[:5]
'Hello'
The array substitute in Python with some added functionality is a List. A list is a type of container, which is used to store multiple data items at the same time. It is ordered (i.e. it can be indexed).
lst = [2,3,'a','b',5.6,True, 1+3j]
type(lst)
list
print(lst)
[2, 3, 'a', 'b', 5.6, True, (1+3j)]
It can also contain another list within itself. This is how higher dimensional arrays can be stored.
Indexing is the same in lists as it is in strings. For a 2-D array (list of lists), we have to use indexing as shown below.
twod_arr = [[0,1],[2,3]]
twod_arr[0][0]
0
A dictionary stores pairs of key-value pairs. For those of you who know hashing, dictionaries are nothing but an implementation of a hashing function.
Basically, in lists, we used default indexes(0,1,2,etc). Here, we can define custom indices. They are known as keys. They can then store corresponding values. They are implemented using hash functions.
my_dict = {'b':'beauty','j':"joy"}
my_dict['b']
'beauty'
Thus, we can now have strings act as indices too!
It is a collection of unordered items. It follows the properties of a mathematical set, where no duplicate elements are stored.
my_set = {"DS","AI","DL"}
print(my_set)
{'DS', 'DL', 'AI'}
my_set_2 = {'a','a','b','b'}
print(my_set_2)
{'a', 'b'}
A tuple is a list, which cannot be changed/modified. Tuples are ordered, just like lists.
my_tuple = ("a","b","c")
my_list = ["a","b","c"]
my_tuple[0] = 'd'
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-61-3b4380fe39e6> in <module>() ----> 1 my_tuple[0] = 'd' TypeError: 'tuple' object does not support item assignment
my_list[0] = 'd'
All datatypes have associated built-in methods which help in performing basic tasks on them. We will look at them once we look at functions, and understand objects.
This is used to decide if a statement / a group of statements should be executed, based on a condition.
a = 5
b = 6
if a<b:
print(a)
print("Yes!")
5 Yes!
Observe a few things:
if <expression>:
<statements>
For a complicated condition(using logical operators and/or expressions), we enclose all of it in a bracket.
Now, we can also extend this to execute another block of statements if the condition evaluates to False.
a = 5
b = 6
if a>b:
print(a)
print("Yes!")
else:
print(b)
print("No!")
6 No!
Thus, the keywords 'if' and 'else' are used to execute statements based on a condition.
What do you do if you want to have multiple condition based statement execution?
For example, if a person is considered:
We need another keyword here to make our lives easier, called 'elif'.
height = 4.5
if height<4:
print("Short")
elif height<5:
print("Average")
else:
print("Tall")
Average
The importance of indentation is paramount in Python. It replaces the cumbersome curly brackets that exist in C, and which if you forget to close, can lead to so many problems.
Indentation makes it easy to trace which code block does which part of code belong to. When you have nested loops (explained later), it aids in visual understanding.
A for loop is used to repeat a block of instructions/statements multiple number of times(most common use case for beginners). In Python, it is used to iterate over a sequence of items as well (lists, sets, tuples and even strings).
for i in range(10):
print(i)
0 1 2 3 4 5 6 7 8 9
Here, the variable following for (in this case, i) is assigned values from the sequence of items serially which is referred to after the 'in' keyword. The range() function generates numbers from 0 to the number passed to it. This will become clearer when we study functions. For now, this is standard syntax when we want to generate numbers from 0 to n.
Thus, the variable is assigned values from the sequence mentioned. Another example is given below:
my_list = [1,2,'s','errve',0.4, True]
for i in my_list:
print(i)
1 2 s errve 0.4 True
We can loop through a string as well.
for i in "Hey there!":
print(i)
H e y t h e r e !
In short, we can loop through any collective datatype, fetching every item from the datatype and assigning it to the variable mentioned after the 'for' keyword.
Here, let us have a look at Nested Loops, which are extremely powerful.
When we have a loop within a loop, we have Nested Loops. These can be used to generate various patterns.
for i in range(3):
for j in range(3):
print(i,j)
print()
0 0 0 1 0 2 1 0 1 1 1 2 2 0 2 1 2 2
for i in range(5):
for j in range(i+1):
print('*',end='')
print()
* ** *** **** *****
range(n) goes from 0 to n-1
Thus, using nested loops, you can set a variable inner loop dependent on the outer loop.
Also notice how indentation now makes the code extremely readable.
Here, we can execute a set of statements as long as a condition is true.
a = 10
while(a>0):
print(a)
a-=1
10 9 8 7 6 5 4 3 2 1
Thus, in Python, for loop can iterate over a collective datatype, and a while loop executes until a statement evaluates to False.
The continue statement is used in loops to skip all the following statements in the current code block, and proceed with the next iteration.
a = 10
while(a>0):
a-=1
if(a<5 and a>1):
continue
print(a)
9 8 7 6 5 1 0
The break statement on the other hand, exits the loop being executed.
a = 10
while(a>0):
a-=1
if(a<5 and a>1):
break
print(a)
9 8 7 6 5
Time for a few exercises:
****
*****
******
*****
****